/**
 * 配置
 * */
package org.zmhhxl.sample3.oauth2.a.handler;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.zmhhxl.sample3.oauth2.a.authentications.model.CustomOAuth2User;

import java.io.IOException;
import java.util.function.Consumer;

/**
 * 登录成功处理类
 *
 * @author vains
 */
//@Transactional/*(readOnly = true)*/ // 确保有活跃的Session
                                           // extends SavedRequestAwareAuthenticationSuccessHandler
@Slf4j                                      // implements AuthenticationSuccessHandler
public class LoginSuccessHandler implements AuthenticationSuccessHandler {

   private final AuthenticationSuccessHandler delegate = new SavedRequestAwareAuthenticationSuccessHandler();

//   @Autowired
//   private RemoteThirdPartyService thirdPartyUserService;
//
//   @Autowired
//   private RemoteUserInfoService userInfoService;

   //private final ThirdPartyUserService thirdPartyUserService;
   //private final UserInfoService userInfoService;
   //private final EntityManager entityManager;

//   @Autowired
//   private PlatformTransactionManager transactionManager;

   @Setter
   private Consumer<OAuth2User> oauth2UserHandler = (user) -> {
   };

   @Setter
   private Consumer<OidcUser> oidcUserHandler = (user) -> this.oauth2UserHandler.accept(user);

   @Override
   //@Transactional(readOnly = true) // 确保有活跃的Session
   public void onAuthenticationSuccess(HttpServletRequest request,
                                       HttpServletResponse response,
                                       Authentication authentication
   ) throws IOException {

      log.info("登录成功_全部 sssss ======== {} | {}", authentication.getPrincipal(), authentication.getName());

      if (authentication.getPrincipal() instanceof UserDetails) {
         UserDetails user = (UserDetails) authentication.getPrincipal();
         // 本地密码登录
         log.info("本地密码登录成功 UserDetails sssss ======= {}", user);  // 已经是数据库中的数据，但不含scope
         //this.oauth2UserHandler.accept((OAuth2User)user);
      }

      // 第三方登录
      if (authentication instanceof OAuth2AuthenticationToken) {
         //第三方登录,本地登录不会进入此处
         if (authentication.getPrincipal() instanceof OidcUser) {
            OidcUser user = (OidcUser) authentication.getPrincipal();
            log.info("本地登录成功 OidcUser sssss ======= {}", user);
            this.oidcUserHandler.accept(user);
         } else if (authentication.getPrincipal() instanceof OAuth2User oAuth2User) {  //mapFuzzyPatternMatch
            if(authentication.getPrincipal() instanceof CustomOAuth2User){
               log.info("第三方登录成功1 CustomOAuth2User sssss ======= {}", oAuth2User);  //查看是否CustomOAuth2User
            }
            this.oauth2UserHandler.accept(oAuth2User);
         }
      }

      try {
         this.delegate.onAuthenticationSuccess(request, response, authentication);
      } catch (ServletException e) {
         e.printStackTrace();
      }

   }

}  //end override

//      if (response.isCommitted()) {
//         log.info("已经作出了回应。无法重定向到 " + targetUrl);
//         return;
//      }

      //getRedirectStrategy().sendRedirect(request, response, targetUrl);

//      private String determineTargetUrl(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
//         // 根据authentication对象来确定目标URL
//         // 可以是主页、用户的个人页面或其他任何页面
//         // 示例：返回主页
//         return "/";
//      }

      /*
       * 登录成功后，重定向到登录前访问的页面
       *
       * 1. 获取登录前访问的页面
       * 2. 重定向到登录前访问的页面
       * 3. 登录成功后，将登录前访问的页面保存到session中，以便于登录成功后重定向到该页面
       * 4. 登录成功后，将登录前访问的页面保存到cookie中，以便于登录成功后重定向到该页面
       * 5. 登录成功后，将登录前访问的页面保存到redis中，以便于登录成功后重定向到该页面
       * 6. 登录成功后，将登录前访问的页面保存到数据库中，以便于登录成功后重定向到该页面
       * 7. 登录成功后，将登录前访问的页面保存到mongodb中，以便于登录成功后重定向到该页面
       * 8. 登录成功后，将登录前访问的页面保存到elasticsearch中，以便于登录成功后重定向到该页面
       * 9. 登录成功
       */

//      Result<String> success = Result.success();
//      response.setCharacterEncoding(StandardCharsets.UTF_8.name());
//      response.setContentType(MediaType.APPLICATION_JSON_VALUE);
//      response.getWriter().write(JsonUtils.objectCovertToJson(success));
//      response.getWriter().flush();

//         public void setOAuth2UserHandler(Consumer<OAuth2User> oauth2UserHandler) {
//         this.oauth2UserHandler = oauth2UserHandler;
//      }
//
//      public void setOidcUserHandler(Consumer<OidcUser> oidcUserHandler) {
//         this.oidcUserHandler = oidcUserHandler;
//      }


//   @Autowired
//   public LoginSuccessHandler(ThirdPartyUserService thirdPartyUserService, UserInfoService userInfoService/*, EntityManager entityManager*/) {
//      this.thirdPartyUserService = thirdPartyUserService;
//      this.userInfoService = userInfoService;
//      //this.entityManager = entityManager;
//   }

//SecurityContextHolder.getContext().setAuthentication(authentication);
//log.info("登录成功 authentication ======= {}",authentication.getName());
// 这里可以添加自定义的逻辑，比如记录日志、设置session、重定向到特定页面等
/*
 * PreAuthenticatedAuthenticationToken
 * 根据主类Javadoc中定义的逻辑构建目标URL。
 * */
//String targetUrl = determineTargetUrl(request, response, authentication);
// 无论哪种登陆方式，都不会是JwtAuthenticationToken
//      if (authentication instanceof JwtAuthenticationToken) {
//         //OAuth2User user = (OAuth2User) authentication.getPrincipal();
//         log.info("登录成功 OAuth2User sssss222 ============ {}",authentication.getPrincipal());
//         //this.oauth2UserHandler.accept(user);
//      }


//               String domainUrl = GeneralFunction.extractDomain((String) GeneralFunction.mapFuzzyMatch(oAuth2User.getAttributes(), "url",0.8).entrySet().stream().findFirst().orElse(null).getValue());
////             //ThirdPartyUser thirdPartyUser = thirdPartyUserService.findByThirdPartyIdAndThirdPartyType(oAuth2User.getAttribute("sub"), domainUrl);
////
////             //val provider    = Mono.just(oAuth2User.getAttribute("provider"));
////             log.info("第三方登录成功1 OAuth2User sssss ======= {}", GeneralFunction.mapFuzzyMatch(oAuth2User.getAttributes(), "url",0.9).entrySet().stream().findFirst().orElse(null).getValue());
////             Object provider = GeneralFunction.mapFuzzyMatch(oAuth2User.getAttributes(), "url",0.9).entrySet().stream().findFirst().orElse(null).getValue();
//             // 获取第三方登录的id
//             String sub = oAuth2User.getName();
////             log.info("第三方登录成功2 OAuth2User sssss ======= {} | {} | {}", provider,sub,oAuth2User.getAttributes());
//              if ((domainUrl != null) && (sub != null)) {
////               // 获取第三方登录的域名
////               String domainUrl = GeneralFunction.extractDomain((String) provider);
////
//               Optional<ThirdPartyUser> thirdPartyUser = thirdPartyUserService.findByThirdPartyIdAndThirdPartyDomain(sub, domainUrl).getData();//.getUserInfos().stream().map(UserInfo::getId).findFirst().orElseThrow();
////               log.info("第三方登录成功3 sssss {}", thirdPartyUser);
////
////                //;/*request.getSession(false)*/
//////               TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
//////               //EntityTransaction transaction = entityManager.getTransaction();
//////               try /*(Session session = entityManager.unwrap(Session.class))*/ {
//////                  //transaction.begin(); // 开始事务
//////                  thirdPartyUser = entityManager.merge(thirdPartyUser); // 将对象关联到当前会话
////
////                   //显式加载关联对象
////                   if (thirdPartyUser != null){
////                      Hibernate.initialize(thirdPartyUser.getUserInfos());
////                   }else{
////                      throw ( new RuntimeException(" ====== Third Party User not found") );
////                   }
////                  Long userId = thirdPartyUser.getUserInfos().stream().map(UserInfo::getId).findFirst().orElseThrow(() -> new RuntimeException(" ====== User Info not found"));
////                  log.info("第三方登录成功31 sssss {}", userId);
////                  Optional<UserInfo> user = userInfoService.findById(userId);
//                  log.info("第三方登录成功4 OAuth2User sssss {} | {}", domainUrl, thirdPartyUser.get());
//                  if (!thirdPartyUser.isPresent()) {
//                     log.info("第三方登录成功5 OAuth2User sssss {}", thirdPartyUser.get());
////                     ThirdPartyUser thirdPartyUser1 = new ThirdPartyUser();
////                     thirdPartyUser1.setThirdPartyId(sub);
////                     thirdPartyUser1.setThirdPartyDomain(domainUrl);
////                     thirdPartyUser1.setThirdPartyProtocol(GeneralFunction.extractUrlProtocol((String) oAuth2User.getAttributes().get("url")));
////                     thirdPartyUser1.setThirdPartyType(oAuth2User.getAttribute("provider"));
////                     thirdPartyUserService.save(thirdPartyUser1);
//                  }
////                     if (user.get().isEnabled()) {
////                        Set<GrantedAuthority> authorities = oAuth2User.getAuthorities().stream()
////                                                                .map(role -> new SimpleGrantedAuthority(role.getAuthority()))
////                                                                .collect(Collectors.toSet()); /*.stream().map(GrantedAuthority::getAuthority)*/
////                        Set<GrantedAuthority> roles = user.get().getAuthorities().stream()
////                                                          .map(Role::getRoleCode)
////                                                          .map(SimpleGrantedAuthority::new)
////                                                         .collect(Collectors.toSet());
////
////                        authorities.addAll(roles);  //没有用，无法添加到jwt中
////                        // authentication = new PreAuthenticatedAuthenticationToken(user.get(), null, authorities);
////                        log.info("第三方登录成功6 authorities sssss ======= {}", authorities);
////                        // 登录成功，重定向到用户个人页面user
////                        //response.sendRedirect("/user/info");
////                     } else {
////                        // 登录失败，重定向到登录页面
////                        //response.sendRedirect("/login");
////                     }
////                  }
////
//////                  transactionManager.commit(status);   //事务结束
//////               }catch (Exception e) {
//////                  //if (transactionManager.isActive()) {
//////                     transactionManager.rollback(status);
//////                  //}
//////                  log.error("处理登录成功时发生错误",e);
//////                  throw e; // 根据实际情况处理异常
//////               }//end try
////
//            }
